package com.niubi.yygh.orders.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.wxpay.sdk.WXPayConstants;
import com.github.wxpay.sdk.WXPayUtil;
import com.niubi.yygh.common.exception.YyghException;
import com.niubi.yygh.enums.PaymentTypeEnum;
import com.niubi.yygh.enums.RefundStatusEnum;
import com.niubi.yygh.model.order.OrderInfo;
import com.niubi.yygh.model.order.PaymentInfo;
import com.niubi.yygh.model.order.RefundInfo;
import com.niubi.yygh.orders.service.OrderInfoService;
import com.niubi.yygh.orders.service.PaymentInfoService;
import com.niubi.yygh.orders.service.RefundInfoService;
import com.niubi.yygh.orders.service.WeixinService;
import com.niubi.yygh.orders.util.ConstantPropertiesUtils;
import com.niubi.yygh.orders.util.HttpClient;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;


import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Service
public class WeixinServiceImpl implements WeixinService {
  @Lazy
  @Autowired
  OrderInfoService orderInfoService;

  @Autowired
  PaymentInfoService paymentInfoService;
  @Autowired
  RefundInfoService refundInfoService;

  @Override
  public Map<String, Object> createNative(Long orderId) {
    //根据orderId查询订单信息
    OrderInfo order = orderInfoService.getOrderInfo(orderId);
    if (order == null) {
      throw new YyghException(20001, "空111!!!!!!");
    }
    // 保存交易记录
    paymentInfoService.savePaymentInfo(order);
    //向支付记录表添加记录(支付状态支付中)
    //使用Httpclient调用微信接口,返回二维码地址
    //1、设置参数
    Map paramMap = new HashMap();
    paramMap.put("appid", ConstantPropertiesUtils.APPID);
    System.out.println(ConstantPropertiesUtils.APPID + ConstantPropertiesUtils.PARTNER);
    paramMap.put("mch_id", ConstantPropertiesUtils.PARTNER);
    paramMap.put("nonce_str", WXPayUtil.generateNonceStr());
    Date reserveDate = order.getReserveDate();
    String reserveDateString = new DateTime(reserveDate).toString("yyyy/MM/dd");
    String body = reserveDateString + "就诊" + order.getDepname();
    paramMap.put("body", body);
    paramMap.put("out_trade_no", order.getOutTradeNo());
    //paramMap.put("total_fee", order.getAmount().multiply(new BigDecimal("100")).longValue()+"");
    paramMap.put("total_fee", "1");//为了测试
    paramMap.put("spbill_create_ip", "127.0.0.1");
    paramMap.put("notify_url", "http://guli.shop/api/order/weixinPay/weixinNotify");
    paramMap.put("trade_type", "NATIVE");
    try {
      //设置微信几口路径
      HttpClient client = new HttpClient("https://api.mch.weixin.qq.com/pay/unifiedorder");
      //设置传递参数,参数是xml格式
      String xmlParam = WXPayUtil.generateSignedXml(paramMap, ConstantPropertiesUtils.PARTNERKEY);
      if (xmlParam == null) {
        throw new YyghException(20001, "空222!!!!!!");
      }
      client.setXmlParam(xmlParam);
      client.setHttps(true);
      //发送请求
      client.post();
      //请求微信接口之后,返回数据
      String xml = client.getContent();
      System.out.println("xml = " + xml);
      //xml转换成map
      Map<String, String> resultMap = WXPayUtil.xmlToMap(xml);
      //4、封装返回结果集
      Map<String, Object> map = new HashMap<>();
      map.put("orderId", orderId);
      map.put("totalFee", order.getAmount());
      map.put("resultCode", resultMap.get("result_code"));
      map.put("codeUrl", resultMap.get("code_url"));
      return map;
    } catch (Exception e) {
      throw new YyghException(20001, "支付二维码生成失败");
    }
  }

  @Override
  public Map<String, String> queryWxPayStatus(Long orderId) {
    OrderInfo orderInfo = orderInfoService.getOrderInfo(orderId);
    Map paramMap = new HashMap<>();
    paramMap.put("appid", ConstantPropertiesUtils.APPID);
    paramMap.put("mch_id", ConstantPropertiesUtils.PARTNER);
    paramMap.put("out_trade_no", orderInfo.getOutTradeNo());
    paramMap.put("nonce_str", WXPayUtil.generateNonceStr());
    try {
      HttpClient client = new HttpClient("https://api.mch.weixin.qq.com/pay/orderquery");
      client.setXmlParam(WXPayUtil.generateSignedXml(paramMap, ConstantPropertiesUtils.PARTNERKEY));
      client.setHttps(true);
      client.post();
      String xml = client.getContent();
      Map<String, String> resultMap = WXPayUtil.xmlToMap(xml);
      return resultMap;
    } catch (Exception e) {
      e.printStackTrace();
    }
    return null;
  }

  @Override
  public boolean refund(Long orderId) {
    //微信退款有两个值  订单交易号out_trade_no
    // 存储到支付记录表里面，trade_no查询订单支付状态时候返回  transaction_id
    //1 根据orderId查询支付记录
    QueryWrapper<PaymentInfo> wrapperPayment = new QueryWrapper<>();
    wrapperPayment.eq("order_id", orderId);
    PaymentInfo paymentInfo = paymentInfoService.getOne(wrapperPayment);

    //2 向退款记录表添加记录（退款状态 退款中）
    RefundInfo refundInfo = refundInfoService.saveRefundInfo(paymentInfo);

    //3 调用微信接口进行微信退款
    //3.1 封装微信退款接口需要参数
    Map<String, String> paramMap = new HashMap<>(8);
    paramMap.put("appid", ConstantPropertiesUtils.APPID);       //公众账号ID
    paramMap.put("mch_id", ConstantPropertiesUtils.PARTNER);   //商户编号
    paramMap.put("nonce_str", WXPayUtil.generateNonceStr());
    paramMap.put("transaction_id", paymentInfo.getTradeNo()); //查询支付状态返回值
    paramMap.put("out_trade_no", paymentInfo.getOutTradeNo()); //订单交易号
    paramMap.put("out_refund_no", "tk" + paymentInfo.getOutTradeNo()); //商户退款单号
    //       paramMap.put("total_fee",paymentInfoQuery.getTotalAmount().multiply(new BigDecimal("100")).longValue()+"");
    //       paramMap.put("refund_fee",paymentInfoQuery.getTotalAmount().multiply(new BigDecimal("100")).longValue()+"");
    //TODO 为了测试 0.01
    paramMap.put("total_fee", "1");
    paramMap.put("refund_fee", "1");

    try {
      //3.2 发送请求
      HttpClient client = new HttpClient("https://api.mch.weixin.qq.com/secapi/pay/refund");
      //设置参数
      String paramXml = WXPayUtil.generateSignedXml(paramMap,
              ConstantPropertiesUtils.PARTNERKEY);
      client.setXmlParam(paramXml);
      //https
      client.setHttps(true);
      //设置证书
      client.setCert(true);
      client.setCertPassword(ConstantPropertiesUtils.PARTNER); //证书密码是商户号
      //发送请求
      client.post();
      //4 根据微信退款接口返回值判断
      //如果返回成功，更新退款记录表，退款状态  已经退款
      //返回true
      String xml = client.getContent();
      Map<String, String> resultMap = WXPayUtil.xmlToMap(xml);
      if (null != resultMap && WXPayConstants.SUCCESS.equalsIgnoreCase(resultMap.get("result_code"))) {
        //更新退款状态 已经退款
        refundInfo.setCallbackTime(new Date());
        refundInfo.setTradeNo(resultMap.get("refund_id"));
        refundInfo.setRefundStatus(RefundStatusEnum.REFUND.getStatus());
        refundInfo.setCallbackContent(JSONObject.toJSONString(resultMap));
        refundInfoService.updateById(refundInfo);
        return true;
      }

    } catch (Exception e) {
      throw new YyghException(20001, "退款失败");
    }
    return false;
  }
}
